package com.hoshiicloud.shxping.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.shxping.dto.AccessToken;
import com.hoshiicloud.shxping.dto.UploadFileResponse;
import com.hoshiicloud.shxping.feign.IFileServerFeignClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.ResourceUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.TimeUnit;

/**
 * @author yangcheng
 * @version 1.0
 * @title: WXCore
 * @description: 微信对外工具类
 * @date 2019/6/17 14:19
 * @mail maiboyc@163.com
 */
@Slf4j
public class WXCore {

    private static final String WATERMARK = "watermark";
    private static final String APPID = "appid";
    private static final String ACCESS_TOKEN_KEY = "access_token";
    /**
     * 解密数据
     *
     * @return String
     * @throws Exception
     */
    public static String decrypt(String appId, String encryptedData, String sessionKey, String iv) {
        String result = "";
        try {
            AES aes = new AES();
            byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
            if (null != resultByte && resultByte.length > 0) {
                result = new String(WxPKCS7Encoder.decode(resultByte));
                JSONObject jsonObject = JSON.parseObject(result);
                String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString(APPID);
                if (!appId.equals(decryptAppid)) {
                    result = "";
                }
            }
        } catch (Exception e) {
            result = "";
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 获取微信access_token
     * @param redisTemplate redis访问对象
     * @param appId         微信appId
     * @param appSecret     微信appSecret
     * @return Response<String>
     */
    public static Response<String> getAccessToken(RedisTemplate<String,Object> redisTemplate, String appId, String appSecret) {
        Response<String> rs;
        Object access_token_cache = redisTemplate.opsForValue().get(ACCESS_TOKEN_KEY);
        if (access_token_cache != null ) {
            rs = Response.data((String) access_token_cache);
        } else {
            RestTemplate restTemplate = new RestTemplate();
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+appSecret;
            // 进行网络请求,访问url接口
            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
            if(responseEntity.getStatusCode() == HttpStatus.OK) {
                String responseData = responseEntity.getBody();
                // 解析从微信服务器获得的access_token、expires_in、errcode、errmsg;
                AccessToken accessToken = JSON.parseObject(responseData,AccessToken.class);
                // 获取access_token
                String access_token = accessToken.getAccess_token();
                // 获取expires_in
                Integer expires_in = accessToken.getExpires_in();
                if(StringUtils.isEmpty(access_token) || null == expires_in){
                    log.error("请求微信接口返回数据错误");
                    rs = Response.failed("请求微信接口返回数据错误");
                }else{
                    rs = Response.data(access_token);
                    redisTemplate.opsForValue().set(ACCESS_TOKEN_KEY,access_token,expires_in, TimeUnit.SECONDS);
                }
            } else {
                log.error("请求微信接口失败");
                rs = Response.failed("请求微信接口失败");
            }
        }
        return rs;
    }

    public static Response<String> getUnlimitedCode(RedisTemplate<String,Object> redisTemplate, String appId, String appSecret, String scene, IFileServerFeignClient fileServerFeignClient){
        Response<String> rs = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        File file = null;
        try {
            Response<String> accessToken_rs = getAccessToken(redisTemplate, appId, appSecret);
            if (null != accessToken_rs && accessToken_rs.getCode() == 200 && StringUtils.isNotEmpty(accessToken_rs.getData())) {
                String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+ accessToken_rs.getData();
                    URL object = new URL(url);
                    HttpURLConnection con = (HttpURLConnection) object.openConnection();
                    con.setDoOutput(true);
                    con.setDoInput(true);
                    con.setRequestProperty("Content-Type", "application/json");
                    con.setRequestProperty("Accept", "application/json");
                    con.setRequestProperty("Accept-Charset", "utf-8");
                    con.setRequestMethod("POST");
                    JSONObject data = new JSONObject();
                    data.put("scene", scene);
                    OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream(), "utf-8");
                    wr.write(data.toString());
                    wr.flush();
                    // 显示 POST 请求返回的内容
                    int HttpResult = con.getResponseCode();
                    if (HttpResult == HttpURLConnection.HTTP_OK) {
                        inputStream = con.getInputStream();
                        //new一个文件，存放图片
                        file = new File(scene+".png");
                        if (!file.exists()) {
                            file.createNewFile();
                        }
                        outputStream = new FileOutputStream(file);
                        int len;
                        byte[] buf = new byte[1024];
                        while ((len = inputStream.read(buf, 0, 1024)) != -1) {
                            outputStream.write(buf, 0, len);
                        }
                        outputStream.flush();
                        FileInputStream in_file = new FileInputStream(file);
                        log.info("fileName:"+file.getName());
                        MultipartFile file1 = new MockMultipartFile("file", in_file);
                        Response<UploadFileResponse> file_rs = fileServerFeignClient.uploadFile("obs-7d37",file.getName(),file.getName(),"hh_shequ/qrcode/",true, file1);
                        if (null != file_rs && file_rs.getCode() == 200 && null != file_rs.getData()) {
                            rs = Response.data(file.getName());
                        } else {
                            rs = Response.failed("上传微信二维码到华为云失败");
                        }
                    } else {
                        log.error("发送请求获取二维码,请求失败,"+con.getResponseMessage());
                        rs = Response.failed("发送请求获取二维码,请求失败,"+con.getResponseMessage());
                    }
            } else {
                log.error("获取二维码失败");
                rs = Response.failed("获取二维码失败");
            }
        }catch (Exception e) {
            log.error("获取微信分享二维码异常："+e.getMessage());
            e.printStackTrace();
        }finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (file != null || file.exists()) {
                FileUtils.deleteQuietly(file);
            }
        }
       return rs;
    }


    public static void main(String[] args) throws Exception {

        String appId = "wx4f4bc4dec97d474b";
        String encryptedData = "7dsE5YeqkHgqMQIoxuGud6mjrB+7VvQJqat0DeH7+qmuQK3ssWuMvAIOUpj4bNSk6nuk7qJzO7EgPw2LW/CDdZycY19k0qMd9hSgvxJutiCxWNelnr7ByoA0ZVtzjA2/A6U0gK33YaR1u0QMPQtbiHMb+2zszsCon3YkL+0AtmTvUNGBzq0GzxAE8g9+1dgrOZsTFVKEF4y26CU2Xv8Aqw==";
        String sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";
        String iv = "5un4ZBbAD1fvKSoynzreOw==";
        System.out.println(ResourceUtils.getURL("classpath:").getPath());
    }

}
